
package com.hexinfo.dmpro.sparing.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hexinfo.dmpro.common.utils.CommonConstants;
import com.hexinfo.dmpro.common.utils.ScanCommonConstants;
import com.hexinfo.dmpro.sparing.dto.IgnoreListDTO;
import com.hexinfo.dmpro.sparing.model.SyncAuditBlackList;
import com.hexinfo.dmpro.sparing.dao.SyncAuditBlackListMapper;
import com.hexinfo.dmpro.sparing.model.SyncCompleteLibraryTask;
import com.hexinfo.dmpro.sparing.model.SyncFullAudit;
import com.hexinfo.dmpro.sparing.model.SyncFullAuditTask;
import com.hexinfo.dmpro.sparing.service.SyncAuditBlackListService;
import com.hexinfo.dmpro.sparing.service.SyncAuditWhiteListService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 全量稽核黑名单表
 *
 * @author yemw
 * @date 2024-01-30 16:55:36
 */
@Service
@Slf4j
public class SyncAuditBlackListServiceImpl extends ServiceImpl<SyncAuditBlackListMapper, SyncAuditBlackList> implements SyncAuditBlackListService {

    @Value("${hdfs.tarPrefix}")
    private String tarPrefix;
    @Autowired
    private SyncAuditWhiteListService syncAuditWhiteListService;

    @Override
    public Page queryList(Page page, SyncAuditBlackList syncAuditBlackList) {
        LambdaQueryWrapper<SyncAuditBlackList> wrapper = Wrappers.lambdaQuery();
        wrapper.like(StrUtil.isNotBlank(syncAuditBlackList.getTblDatabaseName()),SyncAuditBlackList::getTblDatabaseName,syncAuditBlackList.getTblDatabaseName())
                .like(StrUtil.isNotBlank(syncAuditBlackList.getTblName()),SyncAuditBlackList::getTblName,syncAuditBlackList.getTblName())
                .eq(StrUtil.isNotBlank(syncAuditBlackList.getMatchPattern()),SyncAuditBlackList::getMatchPattern,syncAuditBlackList.getMatchPattern())
                .eq(StrUtil.isNotBlank(syncAuditBlackList.getIsDefaultRule()),SyncAuditBlackList::getIsDefaultRule,syncAuditBlackList.getIsDefaultRule())
                .eq(StrUtil.isNotBlank(syncAuditBlackList.getIsIgnore()),SyncAuditBlackList::getIsIgnore,syncAuditBlackList.getIsIgnore())
                .eq(StrUtil.isNotBlank(syncAuditBlackList.getIsAudit()),SyncAuditBlackList::getIsAudit,syncAuditBlackList.getIsAudit())
                .eq(StrUtil.isNotBlank(syncAuditBlackList.getIsSerialAudit()),SyncAuditBlackList::getIsSerialAudit,syncAuditBlackList.getIsSerialAudit())
                .eq(SyncAuditBlackList::getDel,CommonConstants.STATUS_NORMAL).orderByDesc(SyncAuditBlackList::getCreateTime);
        Page returnPage = this.baseMapper.selectPage(page, wrapper);
        return returnPage;
    }

    @Override
    public List<String> matchList(String dbName, List<String> tableList, SyncCompleteLibraryTask task) {
        //需要过滤的表名称
        List<String> setList = new ArrayList<>();
        //差集
        List<String> stringList;
        //黑名单模糊匹配列表(默认规则) 模糊匹配 默认规则 不需要稽核
        List<SyncAuditBlackList> blackLists1 = selectListQ(null
                , ScanCommonConstants.ClusterName.MH.value
                ,ScanCommonConstants.ClusterName.TRUE.value
                ,null
                ,ScanCommonConstants.ClusterName.FALSE.value);
        //黑名单模糊匹配列表(非默认规则) 模糊匹配 非默认规则(库名) 不需要稽核
        List<SyncAuditBlackList> blackLists2 = selectListQ(dbName
                ,ScanCommonConstants.ClusterName.MH.value
                ,ScanCommonConstants.ClusterName.FALSE.value
                ,null
                ,ScanCommonConstants.ClusterName.FALSE.value);
        //黑名单精准匹配列表(默认规则) 精准匹配 默认规则 不需要稽核
        List<SyncAuditBlackList> blackLists3 = selectListQ(null
                ,ScanCommonConstants.ClusterName.JZ.value
                ,ScanCommonConstants.ClusterName.TRUE.value
                ,null
                ,ScanCommonConstants.ClusterName.FALSE.value);
        //黑名单精准匹配列表(非默认规则) 精准匹配 非默认规则(库名) 不需要稽核
        List<SyncAuditBlackList> blackLists4 = selectListQ(dbName
                ,ScanCommonConstants.ClusterName.JZ.value
                ,ScanCommonConstants.ClusterName.TRUE.value
                ,null
                ,ScanCommonConstants.ClusterName.FALSE.value);
        List <SyncAuditBlackList> unionList1 = (List<SyncAuditBlackList>) CollUtil.union(blackLists1,blackLists2);
        List <SyncAuditBlackList> unionList2 = (List<SyncAuditBlackList>) CollUtil.union(blackLists3,blackLists4);
        for (String tblName: tableList) {
            String tblNameFlag = "常规";
            //模糊
            for (SyncAuditBlackList list1 : unionList1) {
                if(tblName.contains(list1.getTblName())){
                    setList.add(tblName);
                    tblNameFlag = ScanCommonConstants.ClusterName.MH.value;
                    break;
                }
            }
            //精准
            if("常规".equals(tblNameFlag)){
                for (SyncAuditBlackList list2 : unionList2) {
                    if(tblName.substring(tarPrefix.length()).equals((dbName+"."+list2.getTblName()))){
                        setList.add(tblName);
                        break;
                    }
                }
            }
        }
        if(ObjectUtil.isNotEmpty(setList)){
            stringList = CollUtil.subtractToList(tableList, setList);
        }else{
            stringList = tableList;
        }
        Collections.sort(stringList);
        Collections.sort(setList);
        //添加白名单信息
        stringList.addAll(syncAuditWhiteListService.addWhiteList(dbName));
        task.setTableNameList("========【稽核名单】========\n"+StringUtils.join(stringList,"\r\n")+"\n========【不稽核名单】========\n"+StringUtils.join(setList,"\r\n"));
        task.setTableHdfsNumber(""+stringList.size());
        return stringList;
    }

    @Override
    public IgnoreListDTO ignoreList(String dbName) {
        //需要忽略的表名称
        List<String> jzList = new ArrayList<>();
        List<String> hmList = new ArrayList<>();
        IgnoreListDTO dto = new IgnoreListDTO();
        //黑名单模糊匹配列表(默认规则) 模糊匹配 默认规则 忽略异常
        List<SyncAuditBlackList> blackLists1 = selectListQ(null
                ,ScanCommonConstants.ClusterName.MH.value
                ,ScanCommonConstants.ClusterName.TRUE.value
                ,ScanCommonConstants.ClusterName.TRUE.value
                ,null);
        //黑名单模糊匹配列表(非默认规则) 模糊匹配 非默认规则(库名) 忽略异常
        List<SyncAuditBlackList> blackLists2 = selectListQ(dbName
                ,ScanCommonConstants.ClusterName.MH.value
                ,ScanCommonConstants.ClusterName.FALSE.value
                ,ScanCommonConstants.ClusterName.TRUE.value
                ,null);
        //黑名单精准匹配列表(默认规则) 精准匹配 默认规则 忽略异常
        List<SyncAuditBlackList> blackLists3 = selectListQ(null
                ,ScanCommonConstants.ClusterName.JZ.value
                ,ScanCommonConstants.ClusterName.TRUE.value
                ,ScanCommonConstants.ClusterName.TRUE.value
                ,null);
        //黑名单精准匹配列表(非默认规则) 精准匹配 非默认规则(库名) 忽略异常
        List<SyncAuditBlackList> blackLists4 = selectListQ(dbName
                ,ScanCommonConstants.ClusterName.JZ.value
                ,ScanCommonConstants.ClusterName.FALSE.value
                ,ScanCommonConstants.ClusterName.TRUE.value
                ,null);
        List <SyncAuditBlackList> unionList1 = (List<SyncAuditBlackList>) CollUtil.union(blackLists1,blackLists2);
        List <SyncAuditBlackList> unionList2 = (List<SyncAuditBlackList>) CollUtil.union(blackLists3,blackLists4);
        for (SyncAuditBlackList list: unionList1) {
            hmList.add(list.getTblName());
        }
        for (SyncAuditBlackList list: unionList2) {
            jzList.add(list.getTblName());
        }
        dto.setJzList(jzList);
        dto.setHmList(hmList);
        return dto;
    }

    /**
     *
     * @param matchPattern 模糊匹配/精准匹配
     * @param isDefaultRule 是否默认规则:是,否
     * @param isIgnore 是否忽略异常报错信息:是,否
     * @param isAudit 是否需要稽核:是,否
     * @return
     */
    public List<SyncAuditBlackList> selectListQ(String dbName,String matchPattern,String isDefaultRule,String isIgnore,String isAudit){
        LambdaQueryWrapper<SyncAuditBlackList> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(StrUtil.isNotBlank(dbName),SyncAuditBlackList::getTblDatabaseName,dbName)
                .isNull(StrUtil.isBlank(dbName),SyncAuditBlackList::getTblDatabaseName)
                .eq(StrUtil.isNotBlank(matchPattern),SyncAuditBlackList::getMatchPattern, matchPattern)
                .eq(StrUtil.isNotBlank(isDefaultRule),SyncAuditBlackList::getIsDefaultRule, isDefaultRule)
                .eq(StrUtil.isNotBlank(isIgnore),SyncAuditBlackList::getIsIgnore,isIgnore)
                .eq(StrUtil.isNotBlank(isAudit),SyncAuditBlackList::getIsAudit,isAudit)
                .eq(SyncAuditBlackList::getDel, CommonConstants.STATUS_NORMAL);
        List<SyncAuditBlackList> blackLists = this.getBaseMapper().selectList(wrapper);
        return blackLists;
    }

}
